#ifndef __MOVIE_HPP__
#define __MOVIE_HPP__

#include <iostream>
#include <string>
#include <list>

#include <cstring>
#include <cstdlib>

#include "funcs.hpp"

using namespace std;

struct Movie {
  string title;
  unsigned short int year;
  string media;
  bool suspended;
  list<string> genres;
  list<string> akas;

  Movie() {}
  Movie(const string& str) : title(str) {}

  bool parse_movie(const string& str, size_t end)
  {
    title = str.substr(0, end);
    media = "Movie"; // Per defecte

    // Busquem si està suspesa
    size_t susp = str.rfind("{{SUSPENDED}}", end);
    if ( susp == string::npos ) {
      susp = end;
      suspended = false;
    } else {
      suspended = true;
    }

    // Busquem mitjà i any
    bool fmedia = false;
    bool fyear  = false;
    size_t end_par = susp;
    while( (!fmedia || !fyear) && end_par != string::npos ) {
      end_par = str.rfind('(', end_par);

      if ( !fmedia ) {
	if ( !strncmp(str.c_str()+end_par, "(TV)", 4) ) {
	  media = "TV Movie";
	  fmedia = true;
	} else if ( !strncmp(str.c_str()+end_par, "(V)" , 3) ){
	  media = "Video";
	  fmedia = true;
	} else if ( !strncmp(str.c_str()+end_par, "(VG)", 4) ){
	  media = "Video Game";
	  fmedia = true;
	}
      }
	
      if ( isdigit(str[end_par+1]) || str[end_par+1] == '?' ) {
	fmedia = true;
	fyear  = true;
	if( str[end_par+1] == '?' ) year = 0xFFFF;
	else year = (unsigned short int)atoi(str.c_str()+end_par+1) ;
	/*
	  akas.push_back( str.substr(0, end_par-1) );*/
      }
      
      --end_par;
    }

    trim(title);
    return true;
  }

  bool parse_serie(const string& str, size_t end)
  {
    title = str.substr(0, end);
    media = "TV Show";

    // Busquem si està suspesa.
    size_t susp = str.rfind("{{SUSPENDED}}", end);
    if ( susp == string::npos ) {
      susp = end;
      suspended = false;
    } else {
      suspended = true;
    }

    // Busquem el nom de l'episodi.
    size_t epis_beg = str.rfind('{', susp);
    size_t epis_end = string::npos;
    if ( epis_beg != string::npos )
      epis_end = str.find('}', epis_beg);
    

    // Busquem l'any
    size_t year_pos = str.find("\" (");
    if ( year_pos == string::npos || str[year_pos+3] == '?' )
      year = 0xFFFF;
    else 
      year = (unsigned short int)atoi(str.c_str()+year_pos+3) ;

    trim(title);
    return true;
  }

  bool parse(const string& str)
  {
    size_t end = str.find('\t');
    if ( end == string::npos ) {
      cerr << "TAB NOT FOUND ON MOVIE ENTITY!" << endl;
      return false;
    }

    if ( str[0] == '"' ) return parse_serie(str, end);
    else return parse_movie(str, end);
  }

  void add_genre(const string& str)
  {
    genres.push_back(str);
  }

  void add_aka(const string& aka)
  {
    akas.push_back(aka);
  }

  friend ostream& operator << (ostream& os, const Movie& m)
  {
    os << "<movie title=\""<< xml_escape(m.title) << "\" year=\"" << m.year << "\" ";
    os << "media=\""<< m.media << "\" ";
    os << "suspended=\"" << (m.suspended ? "true" : "false") << "\">" << endl;

    if ( !m.akas.empty() ) {
      os << "  <akas>" << endl;
      for(list<string>::const_iterator it = m.akas.begin(); 
	  it != m.akas.end(); ++it)
	os << "    <aka>" << xml_escape(*it) << "</aka>" << endl;
      os << "  </akas>" <<endl;
    }

    if ( !m.genres.empty() ) {
      os << "  <genres>" << endl;
      for(list<string>::const_iterator it = m.genres.begin(); 
	  it != m.genres.end(); ++it)
	os << "    <genre>" << *it << "</genre>" << endl;
      os << "  </genres>" << endl;
    }

    os << "</movie>" << endl;

    return os;
  }

};

#endif
